package com.cssy.xxkj.logic.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.byd.acegiext.domain.User;
import com.cssy.xxkj.basic.entity.BasicCompanyTestDO;
import com.cssy.xxkj.logic.contants.BillStatusUtil;
import com.cssy.xxkj.logic.contants.BillTypeConstant;
import com.cssy.xxkj.logic.dao.LogicWarehouseHistoryDAO;
import com.cssy.xxkj.logic.dao.LogicWhCheckTaskDAO;
import com.cssy.xxkj.logic.dao.LogicWhCheckTaskItemDAO;
import com.cssy.xxkj.logic.entity.*;
import com.cssy.xxkj.logic.entity.vo.LogicWhCheckTaskItemVO;
import com.cssy.xxkj.logic.service.ILogicHsUtilService;
import com.cssy.xxkj.logic.service.ILogicWarehouseDetailsService;
import com.cssy.xxkj.logic.service.ILogicWarehouseInventoryService;
import com.cssy.xxkj.logic.service.ILogicWhCheckTaskService;
import com.cssy.xxkj.logic.util.OftenMapUtil;
import com.plat.exception.SyBaseException;
import com.plat.helper.SearchCondition;
import com.plat.helper.SearchConditions;
import com.plat.helper.SearchResult;
import com.plat.util.DateUtils;
import com.plat.util.GlobalResLoader;
import com.plat.util.IDCodeTypeUtil;
import com.plat.util.SessionUtil;
import com.yuendong.sy.exception.SyCodeException;
import com.yuendong.sy.po.code.SyCode;
import com.yuendong.sy.service.code.impl.SyCodeService;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
@Service("logicWhCheckTaskService")
public class LogicWhCheckTaskServiceImpl implements ILogicWhCheckTaskService {
	@Resource(name="logicWhCheckTaskDAO")
	private LogicWhCheckTaskDAO logicWhCheckTaskDAO;

	@Resource(name="logicWhCheckTaskItemDAO")
	private LogicWhCheckTaskItemDAO logicWhCheckTaskItemDAO;

	@Resource(name = "syCodeService")
	private SyCodeService syCodeService;

	@Resource(name="logicWarehouseDetailsService")
	private ILogicWarehouseDetailsService logicWarehouseDetailsService;

	@Resource(name = "logicWarehouseInventoryService")
	private ILogicWarehouseInventoryService logicWarehouseInventoryService;

	@Resource(name="logicHsUtilService")
	private ILogicHsUtilService logicHsUtilService;

	@Resource(name="oftenMapUtil")
	private OftenMapUtil oftenMapUtil;

	@Resource(name="logicWarehouseHistoryDAO")
	private LogicWarehouseHistoryDAO logicWarehouseHistoryDAO;

	@Override
	public SearchResult findListByExample(SearchConditions scs)
			throws SyBaseException {
		SearchResult rs=new SearchResult(scs);
		List<LogicWhCheckTaskDO> list= logicWhCheckTaskDAO.find(scs);
		rs.setRecordCount(logicWhCheckTaskDAO.count(scs));
		rs.setResults(list);
		return rs;
	}

	@Override
	public List<LogicWhCheckTaskItemDO> findItemListByExample(SearchConditions scs)
			throws SyBaseException{
		return logicWhCheckTaskItemDAO.find(scs);
	}

	@Override
	public Integer delete(String id, User user) throws SyBaseException {
		return logicWhCheckTaskDAO.deleteLogicWhCheckTaskDOByPrimaryKey(id);
	}

	@Override
	public Integer update(LogicWhCheckTaskDO t, User user)
			throws SyBaseException {
		t.setBizModifyDate(new Date());
		t.setBizModifyName(user.getName());
		t.setBizVersionMark(t.getBizVersion());
		t.setBizVersion(t.getBizVersion()+1);
		return logicWhCheckTaskDAO.updateLogicWhCheckTaskDO(t);
	}

	@Override
	public LogicWhCheckTaskDO save(LogicWhCheckTaskDO t, User user)
			throws SyBaseException {
		t.setBizCreatorDate(new Date());
		t.setBizCreatorName(user.getName());
		t.setBizVersion(1);
		logicWhCheckTaskDAO.insertLogicWhCheckTaskDO(t);
		return t;
	}

	@Override
	public LogicWhCheckTaskDO findListById(String id) throws SyBaseException {
		return logicWhCheckTaskDAO.findLogicWhCheckTaskDOByPrimaryKey(id);
	}

	@Override
	public Integer deleteBizRemoved(String id) throws SyBaseException {
		return logicWhCheckTaskDAO.deleteBizRemoved(id);
	}

	@Override
	public List<LogicWhCheckTaskItemDO> findItemListByCheckTsdkID(String id)
			throws SyBaseException {
		return logicWhCheckTaskItemDAO.findItemByCheckTaskID(id);
	}

	@SuppressWarnings("unused")
	private LogicWhCheckTaskItemVO LogicWhCheckTaskItemDOToLogicWhCheckTaskItemVo(LogicWhCheckTaskItemDO ld) {
		LogicWhCheckTaskItemVO lv=new LogicWhCheckTaskItemVO();
		/*lv.setZd020WhFreeQuantity(ld.getZd020WhFreeQuantity());
		lv.setZd020FreeQuantity(ld.getZd020FreeQuantity());
		lv.setZd019WhOldQuantity(ld.getZd019WhOldQuantity());
		lv.setZd019OldQuantity(ld.getZd019OldQuantity());
		lv.setZd018WhSecondQuantity(ld.getZd018WhSecondQuantity());
		lv.setZd018SecondQuantity(ld.getZd018SecondQuantity());
		lv.setZd017FirstQuantity(ld.getZd017FirstQuantity());
		lv.setZd017WhFirstQuantity(ld.getZd017WhFirstQuantity());
		lv.setZd016HsQuantity(ld.getZd016HsQuantity());
		lv.setZd016WhHsQuantity(ld.getZd016WhHsQuantity());
		lv.setZd021PiCode(ld.getZd021PiCode());
		lv.setZd015BsUnit(ld.getZd015BsUnit());
		lv.setZd015Unit(ld.getZd015Unit());
		lv.setZd014Batch(ld.getZd014Batch());
		lv.setZd013TaxPrice(ld.getZd013TaxPrice());
		lv.setZd013Price(ld.getZd013Price());
		lv.setZd012MaterSize(ld.getZd012MaterSize());
		lv.setZd011MaterQuality(ld.getZd011MaterQuality());
		lv.setZd009MaterBrand(ld.getZd009MaterBrand());
		lv.setZd008MaterColor(ld.getZd008MaterColor());
		lv.setZd007MaterModel(ld.getZd007MaterModel());
		lv.setZd006MaterSpec(ld.getZd006MaterSpec());
		lv.setZd005MaterType(ld.getZd005MaterType());
		lv.setZd004MaterName(ld.getZd004MaterName());
		lv.setZd003MaterCode(ld.getZd003MaterCode());
		lv.setZd002MaterID(ld.getZd002MaterID());
		lv.setZd001TackCode(ld.getZd001TackCode());
		lv.setZd001TaskID(ld.getZd001TaskID());*/
		lv.setId(ld.getId());
		return lv;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void checkTaskSave(HttpServletRequest request, LogicWhCheckTaskDO curAP)
			throws SyBaseException, SyCodeException {
		try {
			String checkdata = request.getParameter("checkdata");
			String flagMark = request.getParameter("flagMark");
			String zdStepDate = request.getParameter("zd008StepDate");
			String deleteDate=request.getParameter("deleteDate");
			if("1".equals(curAP.getZd009BillType())){//日常盘点
				curAP.setZd009BillType(BillStatusUtil.EVERDAYCHECK);
			}
			if("0".equals(curAP.getZd009BillType())){//月度盘点
				curAP.setZd009BillType(BillStatusUtil.MONTHCHECK);
			}
			if(BillStatusUtil.MONTHCHECK.equals(curAP.getZd009BillType())){
				Map<String, Object> paramMap= new HashMap<String, Object>();
				if(StringUtils.isEmpty(zdStepDate)){
					throw new SyBaseException();
				}
				String zdDate=zdStepDate.substring(0, 7);
				paramMap.put("checktime", zdDate);
				paramMap.put("checkWHCode", curAP.getZd001WhCode());
				paramMap.put("billtype", BillStatusUtil.MONTHCHECK);
				paramMap.put("id", curAP.getId());
				//查询在当前月份月度盘点并且不是自己的单据
				List<LogicWhCheckTaskDO> wt=this.findLogicWhCheckTaskDOListByMap(paramMap);
				if(!(wt==null||wt.isEmpty()||wt.size()==0)){
					throw new SyBaseException("本仓库在您选择的月份已经建有月度盘点单,请确认!!!");
				}
			}
			SearchConditions scsClean= new SearchConditions();
			scsClean.setLimitClause(null);
			Map<String , BasicCompanyTestDO> customerMap=oftenMapUtil.getCurMap(scsClean);
			if(StringUtils.isNotBlank(zdStepDate)){
				curAP.setZd008StepDate(DateUtils.stringToDate(zdStepDate));
			}
			curAP.setZd003TaskStatus(flagMark);
			List<LogicWhCheckTaskItemDO> checkTaskItemList = JSONArray.parseArray(checkdata,LogicWhCheckTaskItemDO.class);
			List<LogicWhCheckTaskItemDO> deleteCheckTaskItemList=new ArrayList<LogicWhCheckTaskItemDO>();
			if(StringUtils.isNotEmpty(deleteDate)){
				deleteCheckTaskItemList=JSONArray.parseArray(deleteDate,LogicWhCheckTaskItemDO.class);
			}
			//在当前单据只能选择是时间是本月或者下月（月度盘点）
			SimpleDateFormat sdf= new SimpleDateFormat("yyyyMM");
			String nextMonth=sdf.format(org.apache.commons.lang.time.DateUtils.addMonths(new Date(), 1));
			if(!(sdf.format(curAP.getZd008StepDate()).equals(sdf.format(new Date()))||
					sdf.format(curAP.getZd008StepDate()).equals(nextMonth))){
				if(BillStatusUtil.MONTHCHECK.equals(curAP.getZd009BillType())){
					throw new SyBaseException("您选择的建单时间错误，建单时间只能是本月或者当前月的下一个月");
				}
			}
			//当是月度盘点时，作废所有未完成的日常盘点单据
			if(BillStatusUtil.MONTHCHECK.equals(curAP.getZd009BillType())){
				SearchConditions scs=new SearchConditions();
				scs.addCondition("zd003TaskStatus", BillStatusUtil.WH_CHECK_TASK_FOUR,
						SearchCondition.OP_NOTEQUAL);
				scs.addCondition("zd003TaskStatus", BillStatusUtil.WH_CHECK_TASK_SIX,
						SearchCondition.OP_NOTEQUAL);
				scs.addCondition("zd009BillType",BillStatusUtil.EVERDAYCHECK,SearchCondition.OP_EQUAL);
				scs.addCondition("zd001WhCode",curAP.getZd001WhCode(),SearchCondition.OP_EQUAL);
				List<LogicWhCheckTaskDO> ctList=this.logicWhCheckTaskDAO.find(scs);
				for(LogicWhCheckTaskDO ct:ctList){
					ct.setZd003TaskStatus(BillStatusUtil.WH_CHECK_TASK_SIX);
					this.update(ct, SessionUtil.getUser(request));
				}
			}
			//当为日常盘点单据新建时不得存在本仓库有未完成的月度盘点单据
			if(BillStatusUtil.EVERDAYCHECK.equals(curAP.getZd009BillType())){
				SearchConditions scs=new SearchConditions();
				scs.addCondition("zd003TaskStatus", BillStatusUtil.WH_CHECK_TASK_FOUR,
						SearchCondition.OP_NOTEQUAL);
				scs.addCondition("zd009BillType",BillStatusUtil.MONTHCHECK,SearchCondition.OP_EQUAL);
				scs.addCondition("zd001WhCode",curAP.getZd001WhCode(),SearchCondition.OP_EQUAL);
				List<LogicWhCheckTaskDO> ctList=this.logicWhCheckTaskDAO.find(scs);
				if(!(ctList==null||ctList.isEmpty()||ctList.size()==0)){
					throw new SyBaseException("在本仓库月度盘点期间不得新建日常盘点单!!!!!!");
				}
			}
			if(curAP==null || StringUtils.isBlank(curAP.getId())){
				//新增
				String checkTaskId = IDCodeTypeUtil.getId();
				curAP.setId(checkTaskId);
				String checkTaskCode = syCodeService.getCode(BillTypeConstant.CHECKTASK,BillTypeConstant.CHECKTASK,SyCode.DATE_YYMM,5);
				curAP.setZd002TaskCode(checkTaskCode);
				this.save(curAP, SessionUtil.getUser(request));
				for(LogicWhCheckTaskItemDO checkTaskItem : checkTaskItemList){
					if(checkTaskItem==null){
						continue;
					}
					checkTaskItem.setId(IDCodeTypeUtil.getId());
					checkTaskItem.setZd001TaskId(checkTaskId);
					checkTaskItem.setZd001TackCode(checkTaskCode);
					logicWhCheckTaskItemDAO.insertLogicWhCheckTaskItemDO(checkTaskItem);
				}
			}else{
				//修改
				LogicWhCheckTaskDO checkTask = this.findListById(curAP.getId());
				if(checkTask==null){
					throw new SyBaseException("数据已发生改变，请重新提交");
				}
				if(StringUtils.isNotBlank(zdStepDate)){
					checkTask.setZd008StepDate(DateUtils.stringToDate(zdStepDate));
				}
				checkTask.setZd003TaskStatus(flagMark);
				if(BillStatusUtil.WH_CHECK_TASK_FIVE.equals(flagMark)){
					//驳回
					checkTask.setZd003TaskStatus(BillStatusUtil.WH_CHECK_TASK_ONE);
					int rowUp = this.update(curAP, SessionUtil.getUser(request));
					if(rowUp==0){
						throw new SyBaseException("数据已发生改变，请重新提交.");
					}
				}else if(BillStatusUtil.WH_CHECK_TASK_FOUR.equals(flagMark)){
					User user=SessionUtil.getUser(request);
					//审核通过，修改库存  分为两种状态 一种为月度盘点 直接删除旧有的库存然后插入现有的库存 liubo 20154
					if(BillStatusUtil.MONTHCHECK.equals(curAP.getZd009BillType())){
						// 1 获得当前仓库的现有库存
						SearchConditions scsStorage= new SearchConditions();
						scsStorage.setLimitClause(null);
						scsStorage.addCondition("zd001WhCode", curAP.getZd001WhCode());
						List<LogicWarehouseInventoryDO> storageList=logicWarehouseInventoryService.findListByExample(scsStorage).getResults();
						// 2  插入到保存的旧有库存历史表中
						Map<String, Object> paramMap= new HashMap<String, Object>();
						if(StringUtils.isEmpty(curAP.getZd001WhCode())){
							throw new SyBaseException("用户未选定仓库，或者选择的仓库错误");
						}
						paramMap.put("whCode", curAP.getZd001WhCode());
						Date stepDate=curAP.getZd008StepDate();
						stepDate=org.apache.commons.lang.time.DateUtils.addMonths(stepDate, -1);
						stepDate=DateUtils.getMonthEnd(stepDate);
						for(LogicWarehouseInventoryDO li:storageList){
							LogicWarehouseHistoryDO history = createHistory(
									user, stepDate, li);
							logicWarehouseHistoryDAO.insertLogicWarehouseHistoryDO(history);
						}
						// 跟新现在的盘点完成数据
						for(LogicWhCheckTaskItemDO item : checkTaskItemList){
							if(item==null||StringUtils.isBlank(item.getId())){
								continue;
							}
							BigDecimal hsCyQuantity = item.getZd006HsCyQuantity();
							if(BigDecimal.ZERO.compareTo(hsCyQuantity)==0){
								continue;
							}
							LogicWarehouseDetailsDO ld = this.taskToDetails(curAP, item);
							this.logicWarehouseInventoryService.updateWhAffstockQuantity(ld, user, false);
						}
						LogicWhCheckTaskDO lt=this.logicWhCheckTaskDAO.findLogicWhCheckTaskDOByPrimaryKey(curAP.getId());
						if(lt==null){
							throw new SyBaseException("数据发生已改变");
						}
						lt.setZd003TaskStatus(flagMark);
						this.update(lt, user);
					}else{
						for(LogicWhCheckTaskItemDO checkTaskItem : checkTaskItemList){
							if(checkTaskItem==null||StringUtils.isBlank(checkTaskItem.getId())){
								continue;
							}
							BigDecimal hsCyQuantity = checkTaskItem.getZd006HsCyQuantity();
							if(BigDecimal.ZERO.compareTo(hsCyQuantity)==0){
								continue;
							}
							//修改库存
							LogicWarehouseDetailsDO ld = this.taskToDetails(curAP, checkTaskItem);
							this.logicWarehouseInventoryService.updateWhAffstockQuantity(ld, user, false);
						}
						int rowUp = this.update(checkTask, SessionUtil.getUser(request));
						if(rowUp==0){
							throw new SyBaseException("数据发生改变，请从新提交。");
						}
					}
				}else{
					for(LogicWhCheckTaskItemDO checkTaskItem : checkTaskItemList){
						if(checkTaskItem==null){
							continue;
						}
						//更新PI 和客户
						if(StringUtils.isEmpty(checkTaskItem.getZd011NewPiCode())){
							checkTaskItem.setZd011NewPiCode(null);
						}
						if(StringUtils.isNotEmpty(checkTaskItem.getZd012CustomerName())&&(!checkTaskItem.getZd012CustomerName().equals(checkTaskItem.getZd013OldCustomerName()))){
							BasicCompanyTestDO customer = customerMap.get(checkTaskItem.getZd012CustomerName());
							if(customer==null){
								checkTaskItem.setZd012CustomerName(checkTaskItem.getZd012CustomerName());
								checkTaskItem.setZd012CustomerCode(null);
								checkTaskItem.setZd012CustomerID(null);
							}else{
								checkTaskItem.setZd012CustomerName(customer.getZd003ZhName());
								checkTaskItem.setZd012CustomerCode(customer.getZd001Code());
								checkTaskItem.setZd012CustomerID(customer.getId());
							}
						}
						if(StringUtils.isBlank(checkTaskItem.getId())){
							checkTaskItem.setId(IDCodeTypeUtil.getId());
							checkTaskItem.setZd001TaskId(checkTask.getId());
							checkTaskItem.setZd001TackCode(checkTask.getZd002TaskCode());
							checkTaskItem.setZd004Batch("BC");
							logicWhCheckTaskItemDAO.insertLogicWhCheckTaskItemDO(checkTaskItem);
						}else{
							logicWhCheckTaskItemDAO.updateLogicWhCheckTaskItemDO(checkTaskItem);
						}
					}
					for(LogicWhCheckTaskItemDO checkTaskItem : deleteCheckTaskItemList){
						logicWhCheckTaskItemDAO.deleteLogicWhCheckTaskItemDOByPrimaryKey(checkTaskItem.getId());
					}
					int rowUp = this.update(checkTask, SessionUtil.getUser(request));
					if(rowUp==0){
						throw new SyBaseException("数据发生改变，请从新提交。");
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new SyBaseException(GlobalResLoader.getOpfailed()+ e.getMessage());
		}

	}

	private LogicWarehouseDetailsDO taskToDetails(LogicWhCheckTaskDO curAP,
			LogicWhCheckTaskItemDO item) {
		//修改库存
		LogicWarehouseDetailsDO ld=new LogicWarehouseDetailsDO();
		ld.setZd001BillCode(curAP.getZd002TaskCode());
		ld.setZd002BillType(BillTypeConstant.CHECKTASK);
		ld.setZd003WhCode(curAP.getZd001WhCode());
		ld.setZd003WhId(curAP.getZd001WhId());
		ld.setZd003WhName(curAP.getZd001WhName());
		ld.setZd005MaterialsId(item.getZd002MaterId());
		ld.setZd005MaterialsCode(item.getZd002MaterCode());
		ld.setZd005MaterialsName(item.getZd002MaterName());
		ld.setZd006MaterialsSpec(item.getZd002MaterSpec());
		ld.setZd007MaterialsModel(item.getZd002MaterModel());
		ld.setZd008MaterialsColor(item.getZd002MaterColor());
		ld.setZd008MaterialsQuanlity(item.getZd002MaterQuality());
		ld.setZd008Unit(item.getZd003Unit());//单位
		ld.setZd009BasicUnit(item.getZd003BsUnit());
		ld.setZd011BasicQuantity(item.getZd006HsCyQuantity());//盘点数差异数
		ld.setZd019Batch("BC");
		ld.setZd020PiCode(item.getZd011NewPiCode());
		ld.setZd022ConsumerID(item.getZd012CustomerID());
		ld.setZd022ConsumerCode(item.getZd012CustomerCode());
		ld.setZd022ConsumerName(item.getZd012CustomerName());
		return ld;
	}

	private LogicWarehouseHistoryDO createHistory(User user, Date monthEndDate,
			LogicWarehouseInventoryDO li) {
		LogicWarehouseHistoryDO history= new LogicWarehouseHistoryDO();
		history.setId(IDCodeTypeUtil.getId());
		history.setZd001WhCode(li.getZd001WhCode());
		history.setZd001WhId(li.getZd001WhId());
		history.setZd001WhName(li.getZd001WhName());
		history.setZd002MaterialCode(li.getZd004MaterialsCode());
		history.setZd002MaterialId(li.getZd003MaterialsId());
		history.setZd002MaterialName(li.getZd005MaterialsName());
		history.setZd003MaterialColor(li.getZd008MaterialsColor());
		history.setZd003MaterialModel(li.getZd007MaterialsModel());
		history.setZd003MaterialQuanlity(li.getZd008MaterialsQuanlity());
		history.setZd003MaterialSpec(li.getZd006MaterialsSpec());
		history.setZd004MaterialBatch(li.getZd020Batch());
		history.setZd005MateriaPrice(li.getZd024Price());
		history.setZd006PiCode(li.getZd026PiCode());
		history.setZd007OldBizCreatorDate(li.getBizCreatorDate());
		history.setZd007OldBizCreatorName(li.getBizCreatorName());
		history.setZd007OldBizModifyDate(li.getBizModifyDate());
		history.setZd007OldBizModifyName(li.getBizModifyName());
		history.setZd008CustomerCode(li.getZd028CustomerCode());
		history.setZd008CustomerId(li.getZd028CustomerID());
		history.setZd008CustomerName(li.getZd028CustomerName());
		history.setZd009Quantity(li.getZd009Quantity());
		history.setZd010Unit(li.getZd008Unit());
		history.setZd011Date(monthEndDate);
		history.setBizCreatorDate(new Date());
		history.setBizCreatorName(user.getName());
		return history;
	}


	@Override
	public LogicWhCheckTaskDO findLogicWhCheckTaskDOByMap(
			Map<String, Object> paramMap) throws SyBaseException {
		return logicWhCheckTaskDAO.findLogicWhCheckTaskDOByMap(paramMap);
	}

	@Override
	public List<LogicWhCheckTaskDO> findLogicWhCheckTaskDOListByMap(
			Map<String, Object> paramMap) throws SyBaseException {
		return logicWhCheckTaskDAO.findLogicWhCheckTaskDOListByMap(paramMap);
	}

}
